#include "bullet.h"
#include "bulletManager.h"
#include "gameMath.h"

Bullet::Bullet()
{

}

/*
Bullet::Bullet(stdBullet std, Point p)
{
	setInformation(std, p);
}*/

void Bullet::setInformation(stdBullet std, Point p)
{
	_std = std;
	_std.bitmap.p = p;
	_reMove = false;
	nowFps = nextFps = nowDraw = nextBulletFps = nowReadBullet = nowRead = coumt = 0;
	ax = ay = vx = vy = _rotate = 0;
	init = false;
	alpha = 0;
	playPoint = roundPoint = NULL;
	follow = false;
	_angle = INT_MAX;
	_Rotate = false;
	_round = false;
}

/*
Bullet::Bullet(stdBullet std, Point p, Point* player)
{
	setInformation(std, p, player);
}*/

void Bullet::setInformation(stdBullet std, Point p, Point* play)
{
	_std = std;
	_std.bitmap.p = p;
	_reMove = false;
	nowFps = nextFps = nowDraw = nextBulletFps = nowReadBullet = nowRead = coumt = 0;
	ax = ay = vx = vy = _rotate = 0;
	init = false;
	alpha = 0;
	playPoint = play;
	roundPoint = NULL;
	follow = false;
	_angle = INT_MAX;
	_Rotate = false;
	_round = false;
}

/*
Bullet::Bullet(stdBullet std, Point p, Point* player, int angle)
{
	setInformation(std, p, player, angle);
}*/

void Bullet::setInformation(stdBullet std, Point p, Point* player, int angle)
{
	_std = std;
	_std.bitmap.p = p;
	_reMove = false;
	nowFps = nextFps = nowDraw = nextBulletFps = nowReadBullet = nowRead = coumt = 0;
	ax = ay = vx = vy = _rotate = 0;
	init = false;
	alpha = 0;
	playPoint = player;
	follow = false;
	roundPoint = NULL;
	_angle = angle;
	_Rotate = false;
	_round = false;
}

void Bullet::setInformation(stdBullet std, Point p, Point* play, int angle, int effect, Point* round)
{
	_std = std;
	_std.bitmap.p = p;
	_reMove = false;
	nowFps = nextFps = nowDraw = nextBulletFps = nowReadBullet = nowRead = coumt = 0;
	ax = ay = vx = vy = _rotate = 0;
	init = false;
	alpha = 0;
	playPoint = play;
	roundPoint = NULL;
	follow = false;
	_angle = angle;
	_Rotate = false;
	_round = false;
	effect = effect;
	setRound(round);
}

void Bullet::gameDraw()
{
	if (!_Rotate)
	{
		//cout << _angle;
		float ra = angleToRad(_angle);
		ra = ALLEGRO_PI - ra;
		al_draw_rotated_bitmap(_std.bitmap.bitmap[nowDraw],
			_std.bitmap.w, _std.bitmap.h,_std.bitmap.p.x,
			_std.bitmap.p.y,  ra, 0);
	}else
	{
			/*al_draw_bitmap(_std.bitmap.bitmap[nowDraw],
		_std.bitmap.p.x - _std.bitmap.w,
		_std.bitmap.p.y - _std.bitmap.h, 0);*/
		al_draw_rotated_bitmap(_std.bitmap.bitmap[nowDraw],
			_std.bitmap.w, _std.bitmap.h,_std.bitmap.p.x,
			_std.bitmap.p.y,  _rotate, 0);
	//cout << _std.bitmap.p.x << _std.bitmap.p.y << endl;
	}
}

void Bullet::gameUpdata()
{
	checkOut();
	checkRound();
	_rotate += 0.1;
	coumt++;
	if (coumt%20 == 0)
	{
		nowDraw++;
	}
	if (nowDraw == _std.bitmap.bitmap.size())
	{
		nowDraw = 0;
	}
	if (readFormVector(nextFps) && nowRead != _std.event.size())
	{
		emenyMessage* m = &_std.event[nowRead++];
		if (m->flag == MOVETO)
		{
			waitingFlag = false;
			calcSpd(m);
		}else if (m->flag == WAIT)
		{
			nextFps += m->time;
			waitingFlag = true;
		}else if (m->flag == ENTER)
		{
			nowFps--;
			init = true;
		}
		m = NULL;
	}
	if (readFormVector(nextBulletFps) 
		&& nowReadBullet != _std.bulletEvent.size())
	{
		_m = _std.getBulletMessage(nowReadBullet++);
		if (_m != NULL)
		{
			if (_m->flag == WAIT)
			{
				nextBulletFps += _m->time;
			}else if (_m->flag == SHOTBULLET && _m->effect != ROUND)
			{
				int begin = _m->angle;
				stdBulletLib* lib = 0;
				lib = lib->Instance();
				bulletManager* manager = 0;
				manager = manager->Instance();
				for (int i = 0; i < (int)_m->ay; i++)
				{
					manager->add(lib->getBullet(_m->kind),
						_std.bitmap.p, playPoint, begin);
					begin += (int)_m->ax;
					begin = begin%360;
				}
				nextBulletFps += _m->time;
			}else if (_m->flag == SHOTBULLET && _m->effect == ROUND)
			{
				int begin = _m->angle;
				stdBulletLib* lib = 0;
				lib = lib->Instance();
				bulletManager* manager = 0;
				manager = manager->Instance();
				for (int i = 0; i < (int)_m->ay; i++)
				{
					manager->add(lib->getBullet(_m->kind),
						_std.bitmap.p, playPoint, begin, _m->effect,
						&_std.bitmap.p);
					begin += (int)_m->ax;
					begin = begin%360;
				}
			}else if (_m->flag == REPEAT)
			{
				nowReadBullet = 0;
				nextBulletFps += _m->time;
			}
		}	
	}
	/*while (checkNextMessage())
	{
	}*/
	if (!_round)
	{
		if (follow)
		{
			calcSpd();
		}
		calcSpd(_angle);

		sumSpd();

		if (!waitingFlag)
			move();
	}else
	{
		_angle += ax;
		ax += ay;
		vx += vy;
		calcPoint();
	}
	//cout << follow << endl;
	nowFps++;
}

void Bullet::move()
{
	vx += ax;
	vy += ay;
	_std.bitmap.p.x += vx;
	_std.bitmap.p.y += vy;
}

void Bullet::initDraw()
{
	al_draw_tinted_bitmap(_std.bitmap.bitmap[nowDraw],
		al_map_rgba(alpha, alpha, alpha, alpha),
		_std.bitmap.p.x - _std.bitmap.w,
		_std.bitmap.p.y - _std.bitmap.h, 0);
}

void Bullet::initUpdata()
{
	coumt++;
	if (coumt%20 == 0)
	{
		nowDraw++;
	}
	if (nowDraw == 3)
	{
		nowDraw = 0;
	}
	if (alpha >= 255)
	{
		init = false;
	}
	alpha += 5;
}

void Bullet::draw()
{
	/*if (init)
	{
		initDraw();
	}else*/
		gameDraw();
}

void Bullet::updata()
{
	/*if (init)
	{
		initUpdata();
	}else*/
		gameUpdata();
}

void Bullet::checkOut()
{
	if (_std.bitmap.p.x >= 640 || _std.bitmap.p.x <= 0)
	{
		_reMove = true;
	}
	if (_std.bitmap.p.y >= 480 || _std.bitmap.p.y < 0)
	{
		_reMove = true;
	}
}

bool Bullet::checkNextMessage()
{
	_m = _std.GetMessage(nowRead);
	if (_m == NULL)
	{
		return false;
	}else if (_m->flag == SHOTBULLET)
	{
		stdBulletLib* lib = 0;
		lib = lib->Instance();
		bulletManager* manager = 0;
		manager = manager->Instance();
		manager->add(lib->getBullet(_m->kind),
			_std.bitmap.p, playPoint);
		nowRead++;
		return true;
	}else if (_m->flag == CREATEENEMY)
	{

	}
	return false;
}

void Bullet::calcSpd()
{
	if (playPoint->x > 0 && playPoint->y > 0)
	{
		/*float t = (playPoint->x - _std.bitmap.p.x)*(playPoint->x - _std.bitmap.p.x)
			+ (playPoint->y - _std.bitmap.p.y)*(playPoint->y - _std.bitmap.p.y);
		t = InvSqrt(t);
		vx = _std.spd * t * (playPoint->x - _std.bitmap.p.x);
		vy = _std.spd * t * (playPoint->y - _std.bitmap.p.y);*/
		_angle = al_atan(playPoint->x - _std.bitmap.p.x,
			playPoint->y - _std.bitmap.p.y);
		//cout << _angle << endl;
	}
}

void Bullet::calcSpd(int i)
{
	if (_angle != INT_MAX)
	{
		if (_angle < 0)
		{
			vx = -_std.spd * SIN[-_angle];
			vy = _std.spd * COS[-_angle];
		}else 
		{
			vx = _std.spd * SIN[_angle];
			vy = _std.spd * COS[_angle];
		}
		//cout << vx << " " << vy << endl;
	}
}

void Bullet::calcPoint()
{
	if (roundPoint != NULL)
	{
		_angle = _angle%360;
		//cout << _angle << endl;
		if (_angle < 0)
		{
			_std.bitmap.p.x = roundPoint->x + vx * SIN[-_angle];
			_std.bitmap.p.y = roundPoint->y - vx * COS[-_angle];
		}else
		{
			_std.bitmap.p.x = roundPoint->x + vx * SIN[_angle];
			_std.bitmap.p.y = roundPoint->y + vx * COS[_angle];
		}
	}

}

void Bullet::sumSpd()
{
	if (vx != 0 && vy != 0)
	{
		_std.spd = sqrt((double)(vx*vx + vy*vy));
	}
}

void Bullet::checkRound()
{
	if (_round && roundPoint == NULL)
	{
		_reMove = true;
	}
}

void Bullet::calcSpd(emenyMessage* m)
{
	if (m->kind == LINE)
	{
		follow = _round = false;
		ax = ay = 0;/*
		vx = _std.spd * SIN[m->angle];
		vy = _std.spd * COS[m->angle];*/
	}else if (m->kind == ACCELERATIONX)
	{
		follow = _round = false;
		ax = m->ax;
		ay = 0;/*
		vx = _std.spd * SIN[m->angle];
		vy = _std.spd * COS[m->angle];*/
	}else if (m->kind == ACCELERATIONY)
	{
		follow = _round = false;
		ax = 0;
		ay = m->ay;/*
		vx = _std.spd * SIN[m->angle];
		vy = _std.spd * COS[m->angle];*/
	}else if (m->kind == ACCELERATIONXY)
	{
		follow = _round = false;
		ax = m->ax;
		ay = m->ay;/*
		vx = _std.spd * SIN[m->angle];
		vy = _std.spd * COS[m->angle];*/
	}else if (m->kind == FOLLOW)
	{
		ax = ay = 0;
		_angle = INT_MAX;
		_round = false;
		follow = true;
		if (playPoint->x > 0 && playPoint->y > 0)
		{
			/*float t = (playPoint->x - _std.bitmap.p.x)*(playPoint->x - _std.bitmap.p.x)
				+ (playPoint->y - _std.bitmap.p.y)*(playPoint->y - _std.bitmap.p.y);
			t = InvSqrt(t);
			vx = _std.spd * t * (playPoint->x - _std.bitmap.p.x);
			vy = _std.spd * t * (playPoint->y - _std.bitmap.p.y);*/
			calcSpd();
		}
	}else if (m->kind == RANDOM)
	{
		ax = ay = 0;
		follow = false;
		_round = false;
		int angle = rand() % 360;
		_angle = angle;
		/*vx = _std.spd * SIN[angle];
		vy = _std.spd * COS[angle];*/
	}else if (m->kind == PLAYER)
	{
		ax = ay = 0;
		follow = false;
		_round = false;
		calcSpd();
	}else if (m->kind == ROUND)
	{
		follow = false;
		_round = true;
		ax = m->ax;
		ay = m->ay;
		if (m->angle != 0)
		{
			vx = m->angle;
		}
		vy = m->addition;
	}
	nextFps += m->time;
}

void Bullet::checkHit(Emeny& e)
{
	float r = _std.bitmap.range + e.getRange();
	r = r * r;
	float s = e.getNowPoint() - _std.bitmap.p;
	if (r > s)
	{
		e.getHit(10);
		_reMove = true;
	}
}

void Bullet::checkHit(Boss& e)
{
	float r = _std.bitmap.range + e.getRange();
	r = r * r;
	float s = e.getNowPoint() - _std.bitmap.p;
	if (r > s)
	{
		e.getHit(10);
		_reMove = true;
	}
}